package com.example.dragcontentviewdemo.helper.internal.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.example.dragcontentviewdemo.helper.internal.connector.AttachInfo;
import com.example.dragcontentviewdemo.helper.internal.util.CaculatorUtil;

/**
 * 根视图封装，因为无法对固定的LinearLayout对象进行重载
 */
public class WrapperFrameLayout extends FrameLayout {
    private final static String TAG = "WrapperLinearLayout";
    private final float CONSTANT_MOVE_PRECISION = 1f;
    private View.OnTouchListener mOnTouchListener = null;
    private AttachInfo mAttachInfo;
    private boolean isMoveEventBeConsumedByChildBefore = false;
    private MotionEvent downEvent;


    public WrapperFrameLayout(Context context) {
        super(context);
        setBackground(null);
    }

    public WrapperFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WrapperFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 需要在实例化后立即调用
     */
    public void attach(AttachInfo info) {
        mAttachInfo = info;
    }

    /**
     * 重载拦截事件，intercept没有listener
     * 当mGroupFlags 包含了disallow时就不会执行此方法了，这个得注意一下
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        /*
        1. 如果一开始的down被消费了，那么这个Layout就会生成一个touchTarget，那么之后的move事件都会经过这里
        2. 如果一开始的down无人消费，则touch事件则会直接来到本层，调用本层的handler处理

         */
        debugLog("onIntercept");
        boolean intercept = false;
        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                handleDown(ev);
                break;
            case MotionEvent.ACTION_MOVE:
                intercept = handleInterceptMove(ev);
                break;
            case MotionEvent.ACTION_UP:
                intercept = handleInterceptUp(ev);
                break;
            case MotionEvent.ACTION_CANCEL:
                intercept = handleInterceptCancel(ev);
                break;
            default:
                break;
        }
        return intercept;
    }

    private void handleDown(MotionEvent ev){
        //自己接收一份并向下传递,因为this需要记录状态
        downEvent = MotionEvent.obtain(ev);
        debugLog("ACTION_DOWN");
        mOnTouchListener.onTouch(this, ev);
    }

    private boolean handleInterceptMove(MotionEvent ev){
        boolean intercept = false;
        //手势已经开始，不可被子View阻断
        if (mAttachInfo.mViewIsMoved) {
            debugLog("View is moved");
            intercept = true;
            mOnTouchListener.onTouch(this, ev);
        } else {
            debugLog("view isn't moved, ask child to consume");
            //isMoveEventBeConsumedByChildBefore短路后者，可以保证isInterestedIn只执行一次
            //被consume过后，之后走这里都是return false;
            if (!isMoveEventBeConsumedByChildBefore){
                //添加精度过滤，因为不移动也会产生ACTION_MOVE, 不足时暂时不用拦截
                if (   downEvent != null && ( CaculatorUtil.distance(downEvent, ev)) > 0 ) {
                    downEvent.recycle();
                    downEvent = null;
                    //执行子View询问， isInterested为true就不拦: intercept = false
                    intercept =  !(mAttachInfo.callback != null && mAttachInfo.callback.isInterestedIn(ev));
                    if (!intercept) {
                        debugLog("intercept: " + intercept);
                        isMoveEventBeConsumedByChildBefore = true;
                    }
                    else {
                        //这里会触发移动，并修改mViewIsMoved，保证该路径外层else只会被执行一次
                        intercept = true;
                        mOnTouchListener.onTouch(this,ev);
                    }
                }
                else {
                    mAttachInfo.mCancelNextUp = true;
                }
            }

        }
        return intercept;
    }

    public boolean handleInterceptUp(MotionEvent ev){
        debugLog("ACTION_UP");
        isMoveEventBeConsumedByChildBefore = false;
        if (mAttachInfo.mViewIsMoved) {
            mOnTouchListener.onTouch(this, ev);
            return true;
        }
        return false;
    }

    public boolean handleInterceptCancel(MotionEvent ev){
        //手势取消，reset状态量
        debugLog("ACTION_CANCEL");
        isMoveEventBeConsumedByChildBefore = false;
        return false;
    }

    @Override
    public void setOnTouchListener(OnTouchListener listener) {
        super.setOnTouchListener(listener);
        mOnTouchListener = listener;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        //stub!
        //底下的view会请求不允许拦截，这里不允许请求通过。
    }

    private void debugLog(String msg) {
        Log.d(TAG, msg);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final boolean result = super.onTouchEvent(event);
        Log.d(TAG, "onTouchEvent: " + result);
        return result;
    }
}
